home *** CD-ROM | disk | FTP | other *** search
- _FINDING SIGNIFICANCE IN NOISY DATA_
- by Roy Kimbrell
-
- [LISTING ONE]
-
- #include <stdio.h>
- #include <stdlib.h>
- #include <math.h>
- #include <console.h>
-
- void I_Lfilter(void);
- unsigned Lfilter(double Y, double confidence);
-
- #define MAIN
-
- #define T 15 /* number of historical values */
- #define S 30 /* number of stages */
- #define SIGNIFICANT 1
- #define NOT_SIGNIFICANT !SIGNIFICANT
-
- /* The following macros define the circular buffer. There are T+2 values in
- the buffer to allow exactly T historical values. The "last" and "plast" values
- are additional to the T values and are not used in the computations--they
- exist in the buffer to allow them to be subtracted from current values.
- */
-
- #define prior (now == 0 ? T+1 : now-1)
- #define last (now == T ? 0 : (now == T+1 ? 1 : now+2))
- #define plast (now == T+1 ? 0 : now+1)
- #define cycle (now == T+1 ? now = 0 : now++)
-
- static int now; /* index of the current historical value */
-
- static double Ef; /* final error sum */
- static double priorEf, priorEff; /* prior error sums */
- static double ef[S+1][T+2]; /* array of forward errors */
- static double eb[S+1][T+2]; /* array of backward errors */
- double Y_hat; /* expected Y */
- static double Efb[S+1], Eff[S+1];
-
- void I_Lfilter(void){
-
- int s, t;
- now = 0;
- Ef = priorEf = priorEff = Y_hat = 0.0;
- for(s=0; s<=S; s++){
- Efb[s] = Eff[s] = 0;
- for(t=0; t<=T+1; t++) ef[s][t] = eb[s][t] = 0.0;
- }
- } /* I_Lfilter */
-
- unsigned Lfilter(double Y, double confidence){
-
- double k, z=0.0, sd=0.0;
- int s;
- static unsigned iteration;
-
- ef[0][now] = eb[0][now] = Y;
- for (s=1; s<=S; s++){
- Efb[s] += ef[s-1][now] * eb[s-1][prior] - ef[s-1][last] * eb[s-1][plast];
- Eff[s] += ef[s-1][now] * ef[s-1][now] - ef[s-1][last] * ef[s-1][last];
- k = Efb[s] / Eff[s];
- ef[s][now] = ef[s-1][now] - k * eb[s-1][prior];
- eb[s][now] = eb[s-1][prior] - k * ef[s-1][now];
- }
- Y_hat = Y - ef[S][prior];
- Ef += ef[S][now] - ef[S][last];
- if (iteration != 0){
- sd = sqrt((T * priorEff - priorEf * priorEf)/(T*(T-1)));
- z = (ef[S][prior] - Ef / T) / sd;
- }
- priorEff = Eff[S]; /* use the output of the last stage */
- priorEf = Ef;
- iteration++;
- cycle;
- if (fabs(z) > confidence)
- return SIGNIFICANT;
- else
- return NOT_SIGNIFICANT;
- } /* Lfilter */
-
- #ifdef MAIN
-
- #define CONFIDENCE 2.0
-
- void main(int ac, char **av){
-
- char buf[80];
- unsigned i=0, significant;
- double Y;
- extern double Y_hat;
-
- while (fgets(buf,sizeof(buf),stdin)){
- Y = atof(buf);
- significant = Lfilter(Y,CONFIDENCE);
- printf("%d\t%.4f\t%.4f",i++,Y,Y_hat);
- if (significant)
- printf("\tSIGNIFICANT\n");
- else
- printf("\n");
- }
- } /* main */
-
- #endif
-
-
- Example 1: The value of to reflects trends in the relative
- differences between forward and (prior) backward error values.
-
-
- At stage s,
- for (t = now; t != last; t = prior(t)){
- Efbs = eft s-1 * eb prior(t) s-1;
- Effs = (eft s-1)2;
- }
- ks = F(Efbs/Effs );
-
-
-
- Example 2: Calculating the filtered value.
-
- ef0 now = ef0 now = Y;
- for (s = 1; s # S; s++){
- Efbs += efs-1 now * ebs-1 prior - efs-1 last * ebs-1 plast;
- Effs += efs-1 now * efs-1 now - efs-1 last * efs-1 last ;
- k = F(Efbs ,Effs);
- efs now = efs-1 now - k * ebs-1 prior;
- ebs now = ebs-1 prior - k * efs-1 now;
- /* Comment The following happens to be one way of computing
- o(Y,^) but we actually do it a different way:
- o(Y,^) += k * ebs-1 prior;
- */
- }
- o(Y,^) = Y - efS prior;
- Ef += efS now - efS last;
- if (iteration != 0){
- sd = R(, F(T * priorEff - (priorEf)2,T * (T-1)));
- z = F( B bc [(e S up3(f) S do3(S prior) - F(Ef,T)),sd);
- }
- priorEff = EffS;
- priorEf = Ef;
- iteration++;
- cycle;
- if ( B bc |(z) > confidence)
- return SIGNIFICANT;
- else
- return NOT_SIGNIFICANT;
-
-
-